package com.meiyuetao.myt.job;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lab.s2jh.core.pagination.GroupPropertyFilter;
import lab.s2jh.core.pagination.PropertyFilter;
import lab.s2jh.core.pagination.PropertyFilter.MatchType;
import lab.s2jh.schedule.BaseQuartzJobBean;

import org.apache.commons.collections.CollectionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.h2.util.StringUtils;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;
import com.meiyuetao.myt.md.entity.Commodity;
import com.meiyuetao.myt.md.entity.Commodity.CommodityStatusEnum;
import com.meiyuetao.myt.md.entity.CommodityPic;
import com.meiyuetao.myt.md.service.CommodityPicService;
import com.meiyuetao.myt.md.service.CommodityService;

/**
 * 图片转存
 * 
 * @author harvey
 * 
 */
public class C2cUpdateComPic extends BaseQuartzJobBean {

    private final static Logger logger = LoggerFactory.getLogger(C2cUpdateComPic.class);

    @Override
    protected void executeInternalBiz(JobExecutionContext context) {
        logger.debug("C2cUpdateComPic executing...");
        CommodityService commodityService = this.getSpringBean(CommodityService.class);
        CommodityPicService commodityPicService = this.getSpringBean(CommodityPicService.class);
        Map<String, Object> retMap = Maps.newHashMap();
        GroupPropertyFilter groupPropertyFilter = GroupPropertyFilter.buildDefaultAndGroupFilter();
        groupPropertyFilter.append(new PropertyFilter(MatchType.EQ, "commodityStatus", CommodityStatusEnum.S60IMPORT));
        List<Commodity> commoditys = commodityService.findByFilters(groupPropertyFilter);
        if (CollectionUtils.isNotEmpty(commoditys)) {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            String patternStr = "(http|https)://img.*?(?=\"|\')";
            Pattern reg = Pattern.compile(patternStr);
            String targetURL = "http://img5.iyoubox.com/PutLocalFile.aspx";
            HttpPost post = new HttpPost(targetURL);
            for (Commodity commodity : commoditys) {
                try {
                    String smallPic = commodity.getSmallPic();
                    String specification = commodity.getSpecification();
                    Matcher m = reg.matcher(specification);
                    while (m.find()) {
                        File imageFile = turnUrlToFile(m.group());
                        FileBody fileBody = new FileBody(imageFile);
                        HttpEntity httpEntity = MultipartEntityBuilder.create().addPart("file", fileBody).build();
                        post.setEntity(httpEntity);
                        CloseableHttpResponse httpResponse = httpclient.execute(post);
                        int status = httpResponse.getStatusLine().getStatusCode();
                        String responseBody = EntityUtils.toString(httpResponse.getEntity());
                        if (HttpStatus.SC_OK == status) {
                            logger.debug("Upload complete, response={}", responseBody);
                            String message = responseBody.substring(2);
                            if (responseBody.startsWith("1+")) {
                                retMap.put("error", 0);
                                retMap.put("url", "http://img.iyoubox.com/GetFileByCode.aspx?code=" + message);
                                retMap.put("md5", message);
                                httpResponse.close();
                                String replace = "http://img.meiyuetao.com/" + message;
                                specification = specification.replaceFirst(m.group(), replace);
                            } else {
                                retMap.put("error", 1);
                                retMap.put("message", message);
                            }
                        } else {
                            logger.error("Upload failed, status={}, response={}", status, responseBody);
                            retMap.put("error", 1);
                            retMap.put("message", "Error Status:" + status);
                        }
                        imageFile.delete();
                    }
                    File imageFile = turnUrlToFile(smallPic);
                    FileBody fileBody = new FileBody(imageFile);
                    HttpEntity httpEntity = MultipartEntityBuilder.create().addPart("file", fileBody).build();
                    post.setEntity(httpEntity);
                    CloseableHttpResponse httpResponse = httpclient.execute(post);
                    int status = httpResponse.getStatusLine().getStatusCode();
                    String responseBody = EntityUtils.toString(httpResponse.getEntity());
                    if (HttpStatus.SC_OK == status) {
                        logger.debug("Upload complete, response={}", responseBody);
                        String message = responseBody.substring(2);
                        if (responseBody.startsWith("1+")) {
                            retMap.put("error", 0);
                            retMap.put("url", "http://img.iyoubox.com/GetFileByCode.aspx?code=" + message);
                            retMap.put("md5", message);
                            httpResponse.close();
                            commodity.setSmallPic(message);
                            commodity.setSpecification(specification);
                            commodity.setCommodityStatus(CommodityStatusEnum.S40OFFSALE);
                            commodityService.save(commodity);

                            GroupPropertyFilter picFilter = GroupPropertyFilter.buildDefaultAndGroupFilter();
                            picFilter.append(new PropertyFilter(MatchType.EQ, "commodity", commodity));
                            List<CommodityPic> commodityPics = commodityPicService.findByFilters(picFilter);
                            CommodityPic commodityPic = commodityPics.get(0);
                            String smallPicUrl = uploadPic(retMap, httpclient, post, commodityPic.getSmallPicUrl());
                            commodityPic.setSmallPicUrl(smallPicUrl);
                            String midPicUrl = uploadPic(retMap, httpclient, post, commodityPic.getMidPicUrl());
                            commodityPic.setMidPicUrl(midPicUrl);
                            String bigPicUrl = uploadPic(retMap, httpclient, post, commodityPic.getBigPicUrl());
                            commodityPic.setBigPicUrl(bigPicUrl);
                            commodityPicService.save(commodityPic);
                        } else {
                            retMap.put("error", 1);
                            retMap.put("message", message);
                        }
                    } else {
                        logger.error("Upload failed, status={}, response={}", status, responseBody);
                        retMap.put("error", 1);
                        retMap.put("message", "Error Status:" + status);
                    }
                    imageFile.delete();
                } catch (MalformedURLException e) {
                    logger.error("stream of resource is wrong!");
                    e.printStackTrace();
                    continue;
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
        logger.debug("C2cUpdateComPic execute finished...");
    }

    private String uploadPic(Map<String, Object> retMap, CloseableHttpClient httpclient, HttpPost post, String url) throws Exception, IOException, MalformedURLException,
            FileNotFoundException, ClientProtocolException {
        File imageFile = turnUrlToFile(url);
        FileBody fileBody = new FileBody(imageFile);
        HttpEntity httpEntity = MultipartEntityBuilder.create().addPart("file", fileBody).build();
        post.setEntity(httpEntity);
        CloseableHttpResponse httpResponse = httpclient.execute(post);
        int status = httpResponse.getStatusLine().getStatusCode();
        String responseBody = EntityUtils.toString(httpResponse.getEntity());
        if (HttpStatus.SC_OK == status) {
            logger.debug("Upload complete, response={}", responseBody);
            String message = responseBody.substring(2);
            if (responseBody.startsWith("1+")) {
                retMap.put("error", 0);
                retMap.put("url", "http://img.iyoubox.com/GetFileByCode.aspx?code=" + message);
                retMap.put("md5", message);
                httpResponse.close();
                return message;
            } else {
                retMap.put("error", 1);
                retMap.put("message", message);
            }
        } else {
            logger.error("Upload failed, status={}, response={}", status, responseBody);
            retMap.put("error", 1);
            retMap.put("message", "Error Status:" + status);
        }
        return null;
    }

    private File turnUrlToFile(String smallPic) throws Exception, IOException, MalformedURLException, FileNotFoundException {
        // new一个文件对象用来保存图片，默认保存当前工程根目录
        File imageFile = new File(UUID.randomUUID() + smallPic.substring(smallPic.length() - 4, smallPic.length()));
        if (!StringUtils.isNullOrEmpty(smallPic)) {
            // 创建输出流
            FileOutputStream outStream = new FileOutputStream(imageFile);
            // 得到图片的二进制数据，以二进制封装得到数据，具有通用性
            byte[] data = readInputStream(new URL(smallPic).openStream());
            // 写入数据
            outStream.write(data);
            // 关闭输出流
            outStream.close();
        }
        return imageFile;
    }

    public static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        // 创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        // 每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        // 使用一个输入流从buffer里把数据读取出来
        while ((len = inStream.read(buffer)) != -1) {
            // 用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        // 关闭输入流
        inStream.close();
        // 把outStream里的数据写入内存
        return outStream.toByteArray();
    }
}
